package me.seu.demo.service.netty.handler;

import lombok.extern.slf4j.Slf4j;
import me.seu.demo.service.netty.enums.EventEnum;
import me.seu.demo.service.netty.message.GpsMessage;
import me.seu.demo.service.netty.utils.ByteUtils;

import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 后台工作对象线程
 *
 * @author liangfeihu
 * @number 53669
 * @since 2021/4/1 下午3:23
 */
@Slf4j
public class ProcessRunnable implements Runnable {

    /**
     * 任务队列
     */
    private ConcurrentLinkedQueue<GpsMessage> workQueue = new ConcurrentLinkedQueue<GpsMessage>();

    private volatile boolean isRunning = false;

    /**
     * 向事件队列中添加事件
     */
    public boolean pushUpMsg(GpsMessage msg) {
        if (isRunning) {
            synchronized (workQueue) {
                boolean ret = workQueue.add(msg);
                if (ret) {
                    workQueue.notifyAll();
                }
                return ret;
            }
        } else {
            return false;
        }
    }

    public ProcessRunnable() {
        isRunning = false;
    }

    @Override
    public void run() {
        log.info("worker thread starting...");
        isRunning = true;
        while (true) {
            try {
                GpsMessage msg = null;
                synchronized (workQueue) {
                    msg = workQueue.poll();
                    if (msg == null) {
                        workQueue.wait();
                        continue;
                    }
                }
                EventEnum event = EventEnum.valuesOf(msg.getProtocolNo());
                String protocolNo = ByteUtils.byteToHexString(msg.getProtocolNo());
                if (event == null) {
                    log.error("deviceId={} event 0x{} is null......", msg.getDeviceId(), protocolNo);
                    continue;
                }
                Process process = ProcessManager.getInstance().getProcess(event);
                if (process == null) {
                    log.error("deviceId={} event 0x{} without process", msg.getDeviceId(), protocolNo);
                    continue;
                }
                log.info("===start process the msg=0x{} deviceId={}", protocolNo, msg.getDeviceId());
                process.execute(msg);
            } catch (Exception e) {
                log.error("Worker thread exception", e);
            }

        } // end while
    } // end thread run

}
